package org.springblade.modules.notice.core;

import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import lombok.extern.slf4j.Slf4j;
import org.springblade.core.tool.utils.Func;
import org.springblade.modules.notice.core.channel.NoticeHandlerFactory;
import org.springblade.modules.notice.core.conditon.TriggerConditionStrategy;
import org.springblade.modules.notice.core.mq.DelayNoticeProduce;
import org.springblade.modules.notice.dto.NoticeTaskParam;
import org.springblade.modules.notice.entity.BizMsgConfig;
import org.springblade.modules.notice.entity.BizMsgConfigRelation;
import org.springblade.modules.notice.enums.BusinessType;
import org.springblade.modules.notice.enums.TriggerConditionEnum;
import org.springblade.modules.notice.enums.TriggerNodeEnum;
import org.springblade.modules.notice.service.IBizMsgConfigRelationService;
import org.springblade.modules.notice.service.IBizMsgConfigService;
import org.springblade.modules.notice.vo.BizMsgConfigListParam;
import org.springblade.modules.notice.vo.NoticeTask;
import org.springframework.core.env.Environment;
import org.springframework.scheduling.annotation.Async;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.util.ArrayList;
import java.util.List;

/**
 * @Author ysq
 * @Date 2024/12/02
 * @Description 消息通知处理入口
 */
@Slf4j
@Component
public class Process {

	@Resource
	private IBizMsgConfigService bizMsgConfigService;
	@Resource
	private IBizMsgConfigRelationService bizMsgConfigRelationService;
	@Resource
	private NoticeHandlerFactory noticeHandlerFactory;
	@Resource
	private Environment environment;
	@Resource
	private DelayNoticeProduce delayNoticeProduce;

	/**
	 * 处理业务通知
	 */
	@Async("noticeTaskExecutor")
	public void noticeBusinessProcess(NoticeTaskParam noticeTaskParam) {
		log.info("消息通知处理入口#Process businessType:{},triggerNode:{},triggerCondition:{},bizId:{},tenantId:{},extra:{}",
			BusinessType.getDesc(noticeTaskParam.getBusinessType()), TriggerNodeEnum.getDesc(noticeTaskParam.getTriggerNode()), TriggerConditionEnum.getDesc(noticeTaskParam.getTriggerCondition()),
			noticeTaskParam.getBizId(), noticeTaskParam.getTenantId(), noticeTaskParam.getExtra());

		BizMsgConfigListParam param = BizMsgConfigListParam.builder()
			.businessType(noticeTaskParam.getBusinessType())
			.node(noticeTaskParam.getTriggerNode())
			.tenantId(noticeTaskParam.getTenantId())
			.status(1)
			.build();
		// 如果没有指定触发条件，则默认为通用消息
		if (noticeTaskParam.getTriggerCondition() != null) {
			param.setTriggerCondition(noticeTaskParam.getTriggerCondition());
			param.setCommon(1);
		} else {
			param.setCommon(0);
		}
		// 获取业务消息配置
		List<BizMsgConfig> configs = bizMsgConfigService.getBizMsgConfigList(param);
		if (configs.isEmpty()) {
			return;
		}

		for (BizMsgConfig config : configs) {
			List<BizMsgConfigRelation> relationTemplates = bizMsgConfigRelationService.list(Wrappers.<BizMsgConfigRelation>lambdaQuery()
				.eq(BizMsgConfigRelation::getBizMsgConfigId, config.getId())
				.eq(BizMsgConfigRelation::getTenantId, noticeTaskParam.getTenantId()));
			if (relationTemplates.isEmpty()) {
				continue;
			}

			// 实时消息
			if (config.getPushTime() == 0) {
				// 触发节点条件判断
				if (!TriggerConditionStrategy.get(config.getTriggerCondition()).isTrigger(noticeTaskParam.getBizId())) {
					return;
				}

				for (BizMsgConfigRelation relationTemplate : relationTemplates) {
					NoticeTask task = NoticeTask.builder()
						.bizId(noticeTaskParam.getBizId())
						.channelType(relationTemplate.getChannelType())
						.msgTemplateId(relationTemplate.getMsgTemplateId())
						.businessType(config.getBusinessType())
						.pushType(relationTemplate.getPushType())
						.tenantId(noticeTaskParam.getTenantId())
						.extra(noticeTaskParam.getExtra())
						.callback(noticeTaskParam.getCallback())
						.build();
					// 分派到对应通知渠道执行器
					noticeHandlerFactory.getHandler(relationTemplate.getChannelType()).doHandle(task);
				}
			} else {
				// 延迟消息
				//当前环境
				String curEnvironment = environment.getActiveProfiles()[0];
				List<Long> pushTimeArr = new ArrayList<>();
				// 延迟时间 如果沒有传入时间，则使用配置的延迟时间
				if (noticeTaskParam.getDeliverTime() != null) {
					pushTimeArr.add(noticeTaskParam.getDeliverTime());
				} else {
					String[] delayTimeArr = Func.split(config.getDelayMinute(), ",");
					for (String item : delayTimeArr) {
						try {
							pushTimeArr.add(DateUtil.date().getTime() + Long.parseLong(item) * 60000);
						} catch (NumberFormatException e) {
						}
					}
				}

				for (Long pushTime : pushTimeArr) {
					for (BizMsgConfigRelation relationTemplate : relationTemplates) {
						NoticeTask task = NoticeTask.builder()
							.bizId(noticeTaskParam.getBizId())
							.triggerCondition(config.getTriggerCondition())
							.channelType(relationTemplate.getChannelType())
							.msgTemplateId(relationTemplate.getMsgTemplateId())
							.businessType(config.getBusinessType())
							.pushType(relationTemplate.getPushType())
							.env(curEnvironment)
							.tenantId(noticeTaskParam.getTenantId())
							.extra(noticeTaskParam.getExtra())
							.callback(noticeTaskParam.getCallback())
							.build();
						// 发送task到MQ
						delayNoticeProduce.send(pushTime, JSONObject.toJSONString(task));
					}
				}
			}
		}
	}

}
